package frsf.cidisi.exercise.tp.search;

import frsf.cidisi.exercise.tp.search.actions.*;

import frsf.cidisi.faia.agent.Perception;
import frsf.cidisi.faia.agent.search.Problem;
import frsf.cidisi.faia.agent.search.SearchAction;
import frsf.cidisi.faia.agent.search.SearchBasedAgent;
import frsf.cidisi.faia.agent.Action;
import frsf.cidisi.faia.solver.search.*;

import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.Vector;



public class Indiana_Jones extends SearchBasedAgent {

    /**
     * This method is executed by the simulator to ask the agent for an action.
     */
    @Override
    public Action selectAction() {
        // Creacion de la estrategia de busqueta
        //IStepCostFunction costFunction = new CostFunction();
        //IEstimatedCostFunction heuristic = new Heuristic(); 
        //AStarSearch estrategiaBusqueda = new AStarSearch(costFunction, heuristic);          
        
    	// Instanciación de la estrategia primero en amplitud.-
       //   BreathFirstSearch estrategiaBusqueda = new BreathFirstSearch();
    	
    	
        //Uniform Cost:
    	//IStepCostFunction costFunction = new CostFunction();
    	//UniformCostSearch estrategiaBusqueda = new UniformCostSearch(costFunction);
    	
    	DepthFirstSearch estrategiaBusqueda = new DepthFirstSearch();
        // Instancia un proceso de busqueda indicando como parametro la estrategia a utilizar.
        Search busqueda = new Search(estrategiaBusqueda);

        // Indica que el arbol de busqueda debe ser mostrado para utilizar visualizarlo con eFaiia
       busqueda.setVisibleTree(Search.EFAIA_TREE);

        // Le indica al Solver el proceso de busqueda que debe ejecutar
        this.setSolver(busqueda);

        // Se ejecuta el proceso de seleccion de la accion mas adecuada.
        Action accionSeleccionada = null;
        try {
        	accionSeleccionada =
                    this.getSolver().solve(new Object[]{this.getProblem()});
        } catch (Exception ex) {
            Logger.getLogger(Indiana_Jones.class.getName()).log(Level.SEVERE, null, ex);
        }
       
       
        if(accionSeleccionada!=null){
	        String[] cadenas= accionSeleccionada.toString().split(" ");
	        if(cadenas[0].equals("Viajar")){
	        	Indiana_JonesMain.inter.viajar(cadenas[2]);
	        }
	        
	        if (cadenas[0].equals("Tomar")) {
	        	Indiana_JonesMain.inter.tomarTesoro();
	        }
        }
       
     
        
        // Return the selected action
        return accionSeleccionada;

    }

    public Indiana_Jones() {
       	
    	// Instancia la meta del agente Indiana Jones
        Indiana_Jones_Goal meta = new Indiana_Jones_Goal();
        
        // Instancia el estado inicial del agente
        Indiana_State agState = new Indiana_State();
        
        
        
        this.setAgentState(agState);

        // Se generan las intancias de los operadores del agente
        Vector<SearchAction> operators = new Vector<SearchAction>();
     
      
        
        operators.addElement(new Tomar_tesoro());	
        
        operators.addElement(new ViajarA_Cenede());
        operators.addElement(new ViajarA_Ase());
                
        operators.addElement(new ViajarA_Mixocu());
        operators.addElement(new ViajarA_Vinizaile());
        operators.addElement(new ViajarA_Bresol());
        	
        operators.addElement(new ViajarA_Aragaey());
        operators.addElement(new ViajarA_Bulovos());	
        operators.addElement(new ViajarA_Cabe());	
        operators.addElement(new ViajarA_Ergintone());	
        operators.addElement(new ViajarA_Icaedur());
    	operators.addElement(new ViajarA_Peregary());	
        
          

        // Se inicializa y asigna el problema inicial que debe resolver el agente
        Problem problem = new Problem(meta, agState, operators);
        this.setProblem(problem);
    }


    /**
     * This method is executed by the simulator to give the agent a perception.
     * Then it updates its state.
     * @param p
     */
    @Override
    public void see(Perception p) {
        this.getAgentState().updateState(p);
    }
}
